<?php
class Loader {
	
	var $db = null;
	var $mod = '';
	var $tag = array('title','type','width','height','onblur','field','source','act','hidename','onclick','change','value','onfocus','readonly','default','autoverify','column','link');
	private $ldata;
	
	function __construct($data){
		global $sysdata;
		$this->ldata = $data;
		$this->mod = $data['mod'];
		$this->db = $data['db'];
		$this->data = $data['tpl_data'];
		$this->systemcnf = $sysdata;
		if($data['table_cnf']) $this->curcnf = $data['table_cnf'];
		if($data['sql']) $this->sql = $data['sql'];
	}
	public function base_lists(){ 
		$result = $this->lists();
		$this->data['search_form'] = $this->search();
		$this->data['quick_button'] = $this->quickButton('list');
		$this->data['javascript'] = $this->javascript();
		$this->data['style'] = $this->style();
		$this->data['page'] = $result['pagestr'];
		$this->data['list'] = $result['list'];
		if(!$this->tpl){
			$this->tpl = new Template();
		}
		$this->tpl->data = $this->data;
		$this->tpl->display($this->systemcnf['list_tpl']);
	
	}
	
	public function base_edit(){
		$mod = $this->mod; 
		if($_POST){
			$cfile = APPDATA.'cache/control/'.$mod.'_edit_before_cache.php';
			if(is_file($cfile)) include $cfile;
			//_e($_POST);
			if($this->curcnf['table']){
				foreach($this->curcnf['table'] as $k=>$v){
					$field = get_table_field($this->db,$v);
					unset($field[$this->curcnf['relate_id'][$k]]);
					unset($field[$this->curcnf['field_id']]);
					$data = array();
					foreach($_POST as $kc=>$c){
						if($field[$kc]&&$kc!='field_id'){
							$data[$kc] = $_POST[$kc];
						}
					}
					if(!$curid) $curid = $_GET[$this->curcnf['field_id']];
					if($_GET[$this->curcnf['field_id']]){
						if($data){
							$this->db->update($v,$data,"{$this->curcnf['field_id']} = {$_GET[$this->curcnf['field_id']]}");
						}
					}else{
						$this->db->insert($v,$data);
						if(!$curid) $curid = $this->db->getLastInsertId();
					}
				}
			}
			$cfile = APPDATA.'cache/control/'.$mod.'_edit_after_cache.php';
			if(is_file($cfile)) include $cfile;
		}else{
			$this->data['javascript'] = $this->javascript();
			$this->data['style'] = $this->style();
			$this->data['list'] = $this->edit();
			$this->data['quick_button'] = $this->quickButton('edit');
			//_e($this->data);
			if(!$this->tpl){
				$this->tpl = new Template();
			}
			$this->tpl->data = $this->data;
			$this->tpl->display($this->systemcnf['edit_tpl']);
		}
	}
	public function javascript(){
		$jsstr = '';
		foreach($this->ldata['javascript'] as $v){
			$jsstr .= '<script type="text/javascript" src="'.$v.'"></script>';
		}
		$jspath = APPPATH.'skin/js/'.$this->mod.'.js';
		$jsurl = APPURL.'skin/js/'.$this->mod.'.js';
		if(is_file($jspath)) $jsstr .= '<script type="text/javascript" src="'.$jsurl.'"></script>';
		return $jsstr;
	}
	
	public function style(){
		$stylestr = '';
		foreach($this->ldata['style'] as $v){
			$stylestr .= '<link rel="stylesheet" href="'.$v.'" type="text/css">';
		}
		$stylepath = APPPATH.'skin/css/'.$this->mod.'.css';
		$styleurl = APPURL.'skin/css/'.$this->mod.'.css';
		if(is_file($stylepath)) $stylestr .= '<link rel="stylesheet" rev="stylesheet" href="'.$styleurl.'" type="text/css" />';
		return $stylestr;
	}
	
	public function edit(){
		$form = new FormControl();
		$this->form_control = $form;
		$result = $this->edit_item();
		return $result;
	}
	
	private function edit_item(){
		$result = array();
		$plus_edit_control = $this->load_plus_form_control('edit');
		$result = array();
		if($_GET[$this->curcnf['field_id']]){
			$where = '1 = 1';
			$i = 0;
			while(true){
				$i++;
				if($this->curcnf['table'][$i]){
					$where .= " AND {$this->curcnf['table'][$i]}.{$this->curcnf['relate_id'][$i]} = {$this->curcnf['table'][($i-1)]}.{$this->curcnf['relate_id'][($i-1)]}";
				}else{
					break;
				}
			}
			$where .= " AND {$this->curcnf['table'][0]}.{$this->curcnf['field_id']} = ".$_GET[$this->curcnf['field_id']];
			$sql = "SELECT * FROM ".implode(",",$this->curcnf['table'])." WHERE {$where}";
			//_e($sql);
			$result = $this->db->getRow($sql);
		}

		$cfile = APPDATA.'cache/control/'.$this->mod.'_edit_result_cache.php';
		if(is_file($cfile)) include $cfile;
		
		$editstr = '';
		$fb = array('{APPURL}');
		$fa = array(APPURL);
		foreach($result as $k=>$v){
			$fb[] = '{'.$k.'}';
			$fa[] = $v;
		}
		$this->result = array($fb,$fa);
		$tag = $this->tag;
		foreach($plus_edit_control as $v){
			$before = array();
			$after = array();
			$str = str_replace($fb,$fa,$v);
			preg_match_all('/<main>(.*)<\/main>/Us',$str,$main);
			foreach($main[0] as $n){
				$before[] = $n;
				$row = array();
				foreach($tag as $m){
					preg_match('/<'.$m.'>(.*)<\/'.$m.'>/Us',$n,$t);
					if(!empty($t[1])){
						if($m=='field'){ 
							$row['name'] = $t[1];
						}
						$row[$m] = preg_replace('/{(.*)}/U','$1',$t[1]);
					}
					
				}
				if(isset($result[$row['name']])) $row['value'] = $result[$row['name']];
				if(!$row['value']&&$_GET[$row['name']]) $row['value'] = $_GET[$row['name']];
				$after[] = $this->form_control->$row['type']($row);
			}
			
			$formstr = str_replace($before,$after,$str);
			preg_match('/<label>(.*)<\/label>/U',$formstr,$label);
			$formstr = trim(preg_replace('/<(author|remark|label|javascript|style)>.*<\/(author|remark|label|javascript)>/Us','',$formstr));
			preg_match('/<model>(.*)<\/model>/U',$formstr,$model);
			if($model[1]){
				$model_result = load_model($model[1],$result);
				$formstr = str_replace('<model>'.$model[1].'</model>',$model_result,$formstr);
			}
			$eresult[] = array('label'=>$label[1],'value'=>$formstr);
		}
		return $eresult;
	}
	
	public function search(){
		$form = new FormControl();
		$this->form_control = $form;
		$result = $this->search_item();
		return $result;
	}
	
	private function search_item(){
		$fb = array('{APPURL}');
		$fa = array(APPURL);	
		$plus_search_control = $this->load_plus_form_control('search');
		$tag = $this->tag;
		foreach($plus_search_control as $v){
			$before = array();
			$after = array();
			$str = str_replace($fb,$fa,$v);
			preg_match_all('/<main>(.*)<\/main>/Us',$str,$main);
			foreach($main[0] as $n){
				$before[] = $n;
				$row = array();
				foreach($tag as $m){
					preg_match('/<'.$m.'>(.*)<\/'.$m.'>/Us',$n,$t);
					if(!empty($t[1])){
						if($m=='field'){ 
							$row['name'] = $t[1];
						}
						$row[$m] = preg_replace('/{(.*)}/U','$1',$t[1]);
					}
				}
				if(!$row['value']) $row['value'] = $_GET[$row['field']];
				$after[] = $this->form_control->$row['type']($row);
			}
			$formstr = str_replace($before,$after,$str);
			preg_match('/<label>(.*)<\/label>/U',$formstr,$label);
			$formstr = trim(preg_replace('/<(author|remark|label|javascript|style)>.*<\/(author|remark|label|javascript)>/Us','',$formstr));
			$result[] = array('label'=>$label[1],'value'=>$formstr);
		}
		return $result;
	}
	public function quickButton($type){
		$quickButtonFile = APPCONTROL.''.$type.'/'.$this->mod.'/quick_button.xml';
		$str = @file_get_contents($quickButtonFile);
		preg_match_all('/<main>(.*)<\/main>/Us',$str,$main);
		foreach($main[0] as $n){
			$before[] = $n;
			$row = array();
			foreach($this->tag as $m){
				preg_match('/<'.$m.'>(.*)<\/'.$m.'>/Us',$n,$t);
				if(!empty($t[1])){
					if($m=='field'){ 
						$row['name'] = $t[1];
					}
					$row[$m] = preg_replace('/{(.*)}/U','$1',$t[1]);
				}
			}
			if(!$row['value']) $row['value'] = $_GET[$row['field']];
			$after[] = $this->form_control->$row['type']($row);
		}
		$formstr = str_replace($before,$after,$str);
		$formstr = trim(preg_replace('/<(author|remark|label|javascript|style)>.*<\/(author|remark|label|javascript)>/Us','',$formstr));
		if($this->result){
			$formstr = str_replace($this->result[0],$this->result[1],$formstr);
		}
		if($_GET){
			foreach($_GET as $k=>$v){
				$formstr = str_replace('{'.$k.'}',$v,$formstr);
			}
		}
		return $formstr;
	}
	private function lists(){
		$list_cache = $this->create_plus_list_cache();
		$where = '1 = 1';
		$i = 0;
		
		while(true){
			$i++;
			if($this->curcnf['table'][$i]){
				$where .= " AND {$this->curcnf['table'][$i]}.{$this->curcnf['relate_id'][$i]} = {$this->curcnf['table'][($i-1)]}.{$this->curcnf['relate_id'][($i-1)]}";
			}else{
				break;
			}
		}
		
		$this->load_plus_form_control('search');
		$cfile = APPDATA.'cache/control/'.$this->mod.'_search_before_cache.php';
		if(is_file($cfile)) include $cfile;

		if($this->curcnf['table']){
			$table_field = @get_table_field($this->db,implode(",",$this->curcnf['table']));
			$xmlcache = @file_get_contents(APPDATA.'cache/control/'.$this->mod.'search_control_cache.xml');
			foreach($table_field as $field=>$v){
				if($_GET[$this->curcnf['field_id']]&&$field==$_GET[$this->curcnf['field_id']]){
					$where .= " AND {$this->curcnf['table'][0]}.{$this->curcnf['field_id']} = '{$_GET[$this->curcnf['field_id']]}'";
				}else{
					$type = '=';
					preg_match('/<main>.*<field>'.$field.'<\/field>.*<link>(.*)<\/link>.*<\/main>/Us',$xmlcache,$g);
					if($g[1]){
						$type = $g[1];
					}
					if($_GET[$field]){
						if($type == 'like'){
							$where .= " AND {$field} LIKE '%{$_GET[$field]}%'";
						}else{
							$where .= " AND {$field} = '{$_GET[$field]}'";
						}
					}
				}
			}
		}
		
		if($sort) $sort = 'ORDER BY '.$sort;
		if($this->sql){
			$sql = $this->sql." WHERE {$where} {$sort}";
		}else{
			$sql = "SELECT * FROM ".implode(",",$this->curcnf['table'])." WHERE {$where} {$sort}";
		}

		$result = show_page($this->db,$sql);
		$arr = $result['list'];
		$page = $result['page'];
		
		$cfile = APPDATA.'cache/control/'.$this->mod.'_list_before_cache.php';
		if(is_file($cfile)) include $cfile;

		$list = array();
		$liststr = '';
		//$i=0;
		foreach($arr as $v){
			$row = array();
			if($list_cache['list']){
				foreach($list_cache['list']['value'] as $km=>$m){
					$m = str_replace(array('{APPURL}'),array(APPURL),$m);
					foreach($v as $kx=>$x){
						$m = str_replace('{'.$kx.'}',$x,$m);
					}
					foreach($this->systemcnf as $kz=>$z){
						$m = str_replace('{'.$kz.'}',$z,$m);
					}
					$align = 'center';
					if($list_cache['list']['align'][$km]) $align = $list_cache['list']['align'][$km];
					$row[] = array("align"=>$align,"val"=>$m);
				}
			}
			$list[] = $row;
		}
		return array("pagestr"=>$page,"list"=>array("tlist"=>$list_cache['title'],"blist"=>$list));
	
	}
	
	private function load_plus_form_control($type){

		$this->modtype = $type;
		$cache = APPDATA.'cache/control/'.$this->mod.$type.'_control_cache.xml';
		if(!is_file($cache)){
			$controlpath = APPCONTROL.''.$type.'/'.$this->mod.'/';
			if(!is_dir($controlpath)){
				mkdir($controlpath);
			}
			$controldatapath = APPDATA.'control/'.$type.'/'.$this->mod.'.php';
			if(!is_file($controldatapath)){
				$darr = array();
				if($type=='search') $darr[] = 'sort';
				file_put_contents($controldatapath,"<?php\nreturn ".var_export($darr,true)."\n?>");
			} 
			$cnf = include $controldatapath;
			$str = '';
			if(count($cnf)>0&&$cnf!=1){
				foreach($cnf as $v){
					if($str) $str .= "<control>\n";
					$str .= file_get_contents(APPCONTROL.''.$type.'/'.$this->mod.'/'.$v.'.xml');
				} 
			}
			if($type=='search'){
				$sortFile = APPCONTROL.''.$type.'/'.$this->mod.'/sort.xml';
				if(!is_file($sortFile)) file_put_contents($sortFile,$this->globalControl('sort'));
			}
			$bottomFile = APPCONTROL.''.$type.'/'.$this->mod.'/bottom.xml';
			if(!is_file($bottomFile)&&$type=='edit') file_put_contents($bottomFile,$this->globalControl('edit_jump'));
			
			if($type=='edit'){
				$quickButton = APPCONTROL.''.$type.'/'.$this->mod.'/quick_button.xml';
				if(!is_file($quickButton)) file_put_contents($quickButton,'');
			}
			
			$topFile = APPCONTROL.''.$type.'/'.$this->mod.'/top.xml';
			
			$topstr = $this->globalControl('search_top');
			if(!is_file($topFile)) file_put_contents($topFile,$topstr);
			
			$bottomFile = APPCONTROL.''.$type.'/'.$this->mod.'/bottom.xml';
			if(!is_file($bottomFile)) file_put_contents($bottomFile,'');
			$allstr = @file_get_contents($topFile).$str.@file_get_contents($bottomFile);
			$this->create_javascript($allstr);
			$this->create_style($allstr);
			$this->create_plus_cache($controldatapath,$allstr);
			$allstr = preg_replace('/<(javascript|style|plus|before|after|result)>(.*)<\/(javascript|style|plus|before|after|result)>/Us','',$allstr);
			file_put_contents($cache,$allstr);
		}
		return explode("<control>",file_get_contents($cache));
	}
	private function create_javascript($str){
		preg_match_all('/<javascript>(.*)<\/javascript>/Us',$str,$javascript);
		if($javascript[1]){
			foreach($javascript[1] as $j){
				$javascriptstr .= $j."\n";
			}
		}
		preg_match('/getdate\(\)/U',$str,$getdate);
		if($getdate[0]){
			$javascriptstr .= @file_get_contents(APPPATH.'skin/js/date.js');
		}
		if($this->modtype=='list'&&$javascriptstr){
			$this->modjavascript = $javascriptstr;
		}else{
			if($this->modjavascript) $javascriptstr .= "\n".$this->modjavascript;
			if($javascriptstr){
				$javascriptstr = str_replace(array('{APPURL}'),array(APPURL),$javascriptstr);
				file_put_contents(APPPATH.'skin/js/'.$this->mod.'.js',$javascriptstr);
			}
		}
	}
	private function create_style($str){
		preg_match_all('/<style>(.*)<\/style>/Us',$str,$style);
		if($style[1]){
			foreach($style[1] as $s){
				$stylestr .= $s."\n";
			}
		}
		preg_match('/getdate\(\)/U',$str,$getdate);
		if($getdate[0]){
			$stylestr .= @file_get_contents(APPPATH.'skin/css/date.css');
		}
		if($this->modtype=='list'&&$stylestr){
			$this->modstyle = $stylestr;
		}else{
			if($this->modstyle) $stylestr .= "\n".$this->modstyle;
			if($stylestr){
				file_put_contents(APPPATH.'skin/css/'.$this->mod.'.css',$stylestr);
			}
		}
	}
	private function create_plus_cache($controldatapath,$str){

		$tag = array('before','after','result');
		foreach($tag as $t){
			preg_match_all('/<'.$t.'>(.*)<\/'.$t.'>/Us',$str,$plus);
			if($plus[1]){
				foreach($plus[1] as $p){
					$control = explode("/",$controldatapath);
					$type = $control[count($control)-2];
					$key = "{$this->mod}_{$type}_{$t}";
					$plus_name[$key] .= str_replace(array('<=>'),array('<='),$p);
					/*preg_match_all('/<body>(.*)<\/body>/Us',$p,$body);
					if($body[1]){
						foreach($body[1] as $b){
							$plus_name[$key] .= str_replace(array('<=>'),array('<='),$b);
						}
					}*/
				}
			}
		}

		if($plus_name){
			foreach($plus_name as $kv=>$v){
				preg_match_all('/.*load_cnf\(\'(.*)\'\)\.*/U',$v,$g);
				file_put_contents(APPDATA.'cache/control/'.$kv.'_cache.php',"<?php\n".str_replace(array('$db->','<=>'),array('$this->db->',"<="),$cnfstr."\n".$v)."\n?>");
			}
		}
	}
	private function create_plus_list_cache(){
		$this->modtype = 'list';
		$cache = APPDATA.'cache/control/'.$this->mod.'_list_cache';
		if(!is_file($cache)){
			$controlpath = APPCONTROL.'list/'.$this->mod.'/';
			if(!is_dir($controlpath)){
				mkdir($controlpath);
				chmod($controlpath,0777);
			}
			$controldatapath = APPDATA.'control/list/'.$this->mod.'.php';
			if(!is_file($controldatapath)) file_put_contents($controldatapath,"<?php\nreturn array();\n?>");
			$quickButtonFile = APPCONTROL.'list/'.$this->mod.'/quick_button.xml';
			if(!is_file($quickButtonFile)) file_put_contents($quickButtonFile,'');
			$cnf = include $controldatapath;
			$tag = array('title','value','align','thwidth','width');
			$allstr = '';
			$allstr .= file_get_contents($quickButtonFile);	
			
			$topFile = APPCONTROL.'list/'.$this->mod.'/top.xml';
			if(!is_file($topFile)) file_put_contents($topFile,'');
			$allstr .= file_get_contents($topFile);
			
			$bottomFile = APPCONTROL.'list/'.$this->mod.'/bottom.xml';
			if(!is_file($bottomFile)) file_put_contents($bottomFile,'');
			if(count($cnf)>0&&$cnf!=1){
				foreach($cnf as $v){
					$str = file_get_contents(APPCONTROL.'list/'.$this->mod.'/'.$v.'.xml');
					$allstr .= $str;
					foreach($tag as $t){
						preg_match('/<'.$t.'>(.*)<\/'.$t.'>/Us',$str,$g);
						$list[$t][] = $g[1];
					}
				}
			}
			$allstr .= file_get_contents($bottomFile);
			$title = array();
			if($list['title']){
				foreach($list['title'] as $kv=>$v){
					$row = array();
					$row['val'] = $v;
					if($list['thwidth'][$kv]) $row['width'] = $list['thwidth'][$kv];
					$title[] = $row;
				}
			}
			$this->create_javascript($allstr);
			$this->create_plus_cache($controldatapath,$allstr);
			file_put_contents($cache,serialize(array('title'=>$title,'list'=>$list)));
		}
		return unserialize(file_get_contents($cache));
	}
	private function globalControl($type){
		$sort = '<label>Sort</label>
				<main>
				<title>Sort</title>
				<type>select</type>
				<field>sort</field>
				<source>
					<txt>
					<option>ID-DESC:id_desc</option>
					<option>ID-ASC:id_asc</option>
					</txt>
				</source>
				</main>
				<before>
							if(!$_GET["sort"]) $_GET["sort"] = "id_desc";
							$sortArr = explode("_",$_GET["sort"]);
							$sort = "{$sortArr[0]} $sortArr[1]";						
				</before>';
		$search_top = '<main>
						<type>hidden</type>
						<field>act</field>
						</main>
						<main>
						<type>hidden</type>
						<field>pact</field>
						</main>';	
		$edit_jump = '<after>
					if($_GET["id"]) 
					 {
						$js = "alert(\'Edit Success!\');";
					 }else{
						$js = "alert(\'Add Success!\');";
					 }
					$js .= "var new_window = parent.document.getElementById(\'new_window\');if(new_window){parent.location.reload();}else{window.opener.location.reload();}";
					echo "<Script Language=\'Javascript\'>".$js."window.close();</Script>";	
					</after>';	
		$data = array('sort'=>$sort,'search_top'=>$search_top,'edit_jump'=>$edit_jump);	
		return $data[$type];
	}
}
?>